package org.jwxa.jwxa4j.parser;

import java.util.LinkedList;

import org.jsoup.Jsoup;
import org.jsoup.helper.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jwxa.jwxa4j.nodes.AbstractWXNode;
import org.jwxa.jwxa4j.nodes.WXNode;
import org.jwxa.jwxa4j.nodes.WXRoot;

/**
 * 使用Jsoup解析HTML为WXRoot对象
 * @author janjan, xujian_jason@163.com
 * @see https://github.com/jhy/jsoup
 *
 */
public class JsoupHTMLParser extends TreeParserable implements TreeParser {

	public JsoupHTMLParser() {
		this(BuilderConfig.getDefaultInstance());
	}
	
	public JsoupHTMLParser(BuilderConfig config) {
		this(config, null);
	}
	
	public JsoupHTMLParser(TreeFilter[] filterArray) {
		this(BuilderConfig.getDefaultInstance(), filterArray);
	}
	
	public JsoupHTMLParser(BuilderConfig config, TreeFilter[] filterArray) {
		super(config, filterArray);
	}
	
	@Override
	public WXRoot parse(String input) {
		if(StringUtil.isBlank(input)) {
			return null;
		}
		return this.parserWithDocument(Jsoup.parse(input));
	}

	private WXRoot parserWithDocument(Document doc) {
		// 获得body标签
		Element body = doc.body();
		if(doc == null || body.childNodeSize() == 0) {
            return null;
        }
		// 创建Root节点
		WXRoot root = new WXRoot();
		// 存放所有Jsoup节点对象
		LinkedList<Node> jsoupNodes = new LinkedList<Node>();
		// 存放所有jwxa4j节点对象
		LinkedList<WXNode> jwxaNodes = new LinkedList<WXNode>();
		// 将根节点加入集合，做循环基因
		jsoupNodes.add(body); jwxaNodes.add(root);
		// 如果Jsoup节点不为空
		while(!jsoupNodes.isEmpty()) {
			// 获取当前Jsoup节点
			Node currentNode = jsoupNodes.removeFirst();
			// 获得相对于Jsoup节点的jwx4j节点
			WXNode wxCurrentNode = jwxaNodes.removeFirst();
			// 循环当前节点所有子节点
			for(int i=0; i<currentNode.childNodeSize(); ++i) {
                Node childNode = currentNode.childNode(i);
                // 构建节点对象
                WXNode wxChildNode = this.config.getBuilder(childNode.getClass())
                		.build(childNode);
                if(wxChildNode == null) {
                	continue;
                }
                // 过滤节点数据
            	for(TreeFilter filter: this.filters) {
            		filter.doFilter(root, wxChildNode, childNode);
            	}
            	// 子节点添加到当前jwx4j节点
            	((AbstractWXNode)wxCurrentNode).addChild(wxChildNode);
            	// 节点添加到集合
            	jsoupNodes.add(childNode);
            	jwxaNodes.add(wxChildNode);
            }
		}
		return root;
	}

}
